package com.cuixichang.minimalism.core.security.userdetails;

import com.cuixichang.minimalism.basal.utils.TimeUtils;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

public class CredentialDetail implements UserDetails {

    private String password;

    private String username;

    private Long loginId;

    private String groupId;

    private String systemCode;

    private List<String> authorities;

    private Long accountExpired;

    private boolean isAccountNonLocked;

    private Long credentialsExpired;

    private boolean isEnabled;

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
       return Optional.ofNullable(this.authorities)
               .map(authorities-> authorities.stream().map(SimpleGrantedAuthority::new)
                       .collect(Collectors.toList()))
               .orElse(null);
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public String getUsername() {
        return username;
    }

    @Override
    public boolean isAccountNonExpired() {
        if(Objects.nonNull(this.accountExpired)){
            return this.accountExpired - TimeUtils.toMilliSecond(LocalDateTime.now()) > 0;
        }
        return true;
    }

    public Long getAccountExpired() {
        return accountExpired;
    }

    @Override
    public boolean isAccountNonLocked() {
        return isAccountNonLocked;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        if(Objects.nonNull(this.credentialsExpired)){
            return this.credentialsExpired - TimeUtils.toMilliSecond(LocalDateTime.now()) > 0;
        }
        return true;
    }

    public Long getCredentialsExpired() {
        return credentialsExpired;
    }

    @Override
    public boolean isEnabled() {
        return isEnabled;
    }

    public Long getLoginId() {
        return loginId;
    }

    public String getGroupId() {
        return groupId;
    }

    public String getSystemCode() {
        return systemCode;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setLoginId(Long loginId) {
        this.loginId = loginId;
    }

    public void setGroupId(String groupId) {
        this.groupId = groupId;
    }

    public void setSystemCode(String systemCode) {
        this.systemCode = systemCode;
    }

    public void setAuthorities(List<String> authorities) {
        this.authorities = authorities;
    }

    public void setAccountExpired(Long accountExpired) {
        this.accountExpired = accountExpired;
    }

    public void setAccountNonLocked(boolean accountNonLocked) {
        this.isAccountNonLocked = accountNonLocked;
    }

    public void setCredentialsExpired(Long credentialsExpired) {
        this.credentialsExpired = credentialsExpired;
    }

    public void setEnabled(boolean enabled) {
        this.isEnabled = enabled;
    }

    public static Builder builder(){
        return new Builder();
    }


    public static class Builder{
        private CredentialDetail credentialDetail;

        public Builder(){
          this.credentialDetail = new CredentialDetail();
        }

        public Builder password(String password){
            credentialDetail.setPassword(password);
            return this;
        }

        public Builder username(String username){
            credentialDetail.setUsername(username);
            return this;
        }

        public Builder loginId(Long loginId){
            credentialDetail.setLoginId(loginId);
            return this;
        }

        public Builder groupId(String groupId){
            credentialDetail.setGroupId(groupId);
            return this;
        }

        public Builder systemCode(String systemCode){
            credentialDetail.setSystemCode(systemCode);
            return this;
        }

        public Builder authorities(List<String> authorities){
            credentialDetail.setAuthorities(authorities);
            return this;
        }

        public Builder accountNonExpired(Long accountExpired){
            credentialDetail.setAccountExpired(accountExpired);
            return this;
        }

        public Builder accountNonLocked(boolean accountNonLocked){
            credentialDetail.setAccountNonLocked(accountNonLocked);
            return this;
        }

        public Builder credentialsNonExpired(Long credentialsExpired){
            credentialDetail.setCredentialsExpired(credentialsExpired);
            return this;
        }

        public Builder enabled(boolean enabled){
            credentialDetail.setEnabled(enabled);
            return this;
        }

        public CredentialDetail build(){
            return credentialDetail;
        }
    }
}
